<?php

// +----------------------------------------------------------------------
// | 私信
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2024 http://www.yicmf.com, All rights reserved.
// +----------------------------------------------------------------------
// | Author: 微尘 <yicmf@qq.com>
// +----------------------------------------------------------------------

namespace app\event\pos;

use app\common\event\Base;
use app\model\file\Attachment;
use app\model\file\Image as ImageModel;
use app\model\im\ChatGrouping;
use app\model\im\RobotGreetings;
use app\model\store\StoreApp as StoreAppModel;
use app\model\ucenter\User as UserModel;
use app\model\im\Chat as ChatModel;
use app\model\im\ChatContent as ChatContentModel;
use app\event\im\Robot as RobotEvent;
use think\Exception;
use think\facade\Cache;
use think\facade\Cookie;
use think\facade\Db;
use think\facade\Log;

class PosVip extends Base
{
    /**
     * 发送者
     * @var UserModel
     */
    protected UserModel $user;
    /**
     * 参数
     * @var array
     */
    protected array $param;

    protected $from;

    /**
     * 判断用户是否在线
     * @param $uid
     */
    public static function isOnline($uid): int
    {
        $chat_online = Cache::get('chat_online');
        if (isset($chat_online[$uid]) && $chat_online[$uid] > (time() - 30)) {
            return 1;
        } else {
            return 0;
        }
    }

    /**
     * 判断用户是否在线
     * @param $uid
     */
    public static function removeOnline($uid): int
    {
        $chat_online = Cache::get('chat_online');

        if (isset($chat_online[$uid])) {
            unset($chat_online[$uid]);
            UserModel::where('id', $uid)->update(['is_online' => 0]);
            ChatModel::where('to_user_id', $uid)->update(['to_user_is_online' => 0]);
            Cache::set('chat_online', $chat_online);
        }
        return true;
    }

    /**
     * 判断用户是否在线
     * @param $uid
     * @return bool
     */
    public static function setOnline($uid): bool
    {
        UserModel::where('id', $uid)->update(['is_online' => 1]);
        ChatModel::where('to_user_id', $uid)->update(['to_user_is_online' => 1]);
        $chat_online = Cache::get('chat_online');
        $chat_online[$uid] = time();
        Cache::set('chat_online', $chat_online);
        return true;
    }

    /**
     * 设置排队
     * @param $uid
     * @return bool
     */
    public static function setWait($uid): bool
    {

//        $chat_online = Cache::get('chat_wait');
//        $chat_online[$uid] = time();
        Cache::set('chat_wait_' . $uid, time());
        return true;
    }

    /**
     * 获取是否有队列
     * @param $uid
     * @return bool
     */
    public static function getWait($uid = null): bool
    {
        return Cache::pull('chat_wait_' . $uid) ?: false;
    }

    /**
     * 发送短连接消息
     * @param $cid
     * @return bool
     */
    public static function sendShortConnection($cid): bool
    {
        if (!Cache::has('chat_offline')) {
            Cache::set('chat_offline', [$cid]);
        } else {
            Cache::push('chat_offline', $cid);
        }
        return true;
    }


    /**
     * 发送Worker消息
     * @param $cid
     * @param $data
     * @return bool
     */
    public static function sendWorkerJob($cid, $type, $data): bool
    {
        $data['type'] = $type;
        if (!Cache::has('worker_jobs_' . $cid)) {
            Cache::set('worker_jobs_' . $cid, [$data]);
        } else {
            Cache::set('worker_jobs_' . $cid, array_merge(Cache::pull('worker_jobs_' . $cid), [$data]));
        }
        return true;
    }


    /**
     * 顾客初始化会话
     * @param array $param
     * @param UserModel $user
     */
    public function initChat(UserModel $user, array $param, $device = null): array
    {
        try {
            if (!$user) {
                throw new Exception('游客信息异常');
            }
            $chat = $user->chats()->where('status', 1)->where('service_status', 'in', '0,1')->find();
            if (!$chat) {
                //客服获取  未指定 默认机器人
                if (empty($param['service_id'])) {
                    $service = UserModel::where('id', $user['app']['ai_user_id'])->find();
                } else {
//                    $service = UserModel::where('id', $user['store_id'])->where('service_status', 1)->orderRaw('RAND()')->find();
                    $service = UserModel::where('id', $param['service_id'])->find();
                }
                $chat = $this->_initChat($user, $service, $param, $device);
            }
//            Db::startTrans();
            $data['data']['service'] = UserModel::where('id', $chat['to_user_id'])->field('id,nickname,avatar_id,avatar_url,is_online')->find();;
            $data['data']['chat'] = $chat;
            $data['code'] = 0;
//            Db::commit();
            $data['message'] = '获取成功';
        } catch (\Exception $e) {
            // 回滚事务
//            Db::rollback();
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
//				$data['message'] = $e->getMessage();
        }
        return $data;
    }


    /**
     * 访客咨询窗口打开
     * @param array $param
     * @param UserModel $user
     */
    public function close(array $param, UserModel $user, $role = '客服'): array
    {
        try {

            if (!$user) {
                throw new Exception('客服信息异常');
            }

            $chat = $user->chats()->where('id', $this->request->param('chat_id'))->find();
            if (!$chat) {
                throw new Exception('聊天信息不存在');
            }
            self::_close($chat);
            // 增加通知
            self::sendWorkerJob($chat['to_user_id'], 'system_tips', ['content' => $role . '已经关闭了咨询窗口，感谢您的支持！']);
//            Db::startTrans();

            $data['code'] = 0;
//            Db::commit();
            $data['message'] = '获取成功';
        } catch (\Exception $e) {
            // 回滚事务
//            Db::rollback();
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
//				$data['message'] = $e->getMessage();
        }
        return $data;
    }

    /**
     * 访客咨询窗口打开
     * @param array $param
     * @param UserModel $user
     */
    public static function systemCloseChat($chat, $role = '客户超时未响应关闭'): array
    {
        try {


            self::_close($chat);
            // 增加通知
//            Db::startTrans();

            $data['code'] = 0;
//            Db::commit();
            $data['message'] = '获取成功';
        } catch (\Exception $e) {
            // 回滚事务
//            Db::rollback();
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
//				$data['message'] = $e->getMessage();
        }
        return $data;
    }

    protected static function _close($chat)
    {

        // 设置结束，·
        $chat['service_status'] = 2;
        $chat->save();
        $toChat = ChatModel::where('id', $chat['to_chat_id'])->find();
        if ($toChat) {
            $toChat['service_status'] = 2;
            $toChat->save();
        }
        return;
    }

    /**
     * 客服初始化聊天内容
     * @param array $param
     * @param UserModel $user
     */
    public function initConversation(UserModel $user, array $param, $device = null): array
    {
        try {

            if (!$user) {
                throw new Exception('初始化信息异常', 1);
            }
            $chat = $user->chats()->where('status', 1)->where('id', $param['my_chat_id'])->find();
            if (!$chat) {
                // 创建新聊天
                throw new Exception('聊天信息异常');
            }
            if ($chat['service_status'] == 2) {
                $chat['service_status'] = 1;
                $chat['service_count'] = $chat['service_count'] + 1;
                $chat->save();
            }
            if ($chat['queue'] > 0) {
                // 查询排队情况
                $data['data']['wait'] = $this->waitStep($chat);
            } else {
                // 查询是否有聊天记录
                $lists = $chat->contents()->with(['user'])->where('status', 1)->order('create_time', 'DESC')->paginate();
                // ai机器人欢迎语
                $data['data']['lists'] = $lists;
            }
//            Db::startTrans();
            $data['data']['service'] = UserModel::where('id', $chat['to_user_id'])->field('id,nickname,avatar_id,avatar_url,is_online')->find();;
            $data['data']['chat'] = $chat;
            $data['code'] = 0;
//            Db::commit();
            $data['message'] = '获取成功';
        } catch (\Exception $e) {
            // 回滚事务
//            Db::rollback();
            $data['code'] = $e->getCode();
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'line:' . $e->getLine() . 'dd';
//				$data['message'] = $e->getMessage();
        }
        return $data;
    }


    protected function _initChat($user, $toUser, $param, $device = null)
    {
        // 创建新聊天
        $chat = [];
        $chat['remark'] = $toUser['nickname'];
        $chat['store_app_id'] = $user['store_app_id'];
        $chat['store_id'] = $user['store_id'];
        $chat['to_user_id'] = $toUser['id'];
        $chat['from_url'] = isset($param['from_url']) ? $param['from_url'] : '';
        $chat['type'] = 1;
        $chat['relation_id'] = null;
        $customer_product = Cookie::get('customer_product');
        $chat['product'] = [];
        if ($customer_product) {
            $customer_product = json_decode($customer_product, true);
            $chat['product'] = $customer_product;
        }
        if ($toUser['type'] == 2) {
            // 机器人不限制
            $chat['queue'] = 0;
            $chat['service_status'] = 1;
        } else {
            // 正在咨询数量
            $work = ChatModel::where('user_id', $toUser['id'])
                ->where('service_status', 1)
                ->where('status', 1)->count();
            if ($work >= $user['app']['service_number']) {
                // 需要排队
                $chat['queue'] = $toUser->chats()->where('service_status', 0)
                        ->where('status', 1)
                        ->where('queue', '>', 0)->max('queue') + 1;
                $chat['service_status'] = 0;
            } else {
                $chat['queue'] = 0;
                $chat['service_status'] = 1;
            }
        }
        $chat['service_count'] = 1;
        $chat = $user->chats()->save($chat);
        if (!$chat) {
            throw new Exception('创建信息异常');
        }
        // 新增
        $toChat['type'] = 2;
        $toChat['queue'] = $chat['queue'];
        $toChat['store_id'] = $chat['store_id'];
        $toChat['store_app_id'] = $chat['store_app_id'];
        $toChat['service_status'] = $chat['service_status'];
        $toChat['from_url'] = $chat['from_url'];
        $toChat['no_read_count'] = 0;
        $toChat['service_count'] = 1;
        $toChat['message_count'] = 0;
        $toChat['to_chat_id'] = $chat['id'];
        $toChat['new_content'] = '';
        $toChat['remark'] = $chat['nickname'];
        $toChat['user_id'] = $chat['to_user_id'];
        $toChat['relation_id'] = $chat['relation_id'];
        $toChat['to_user_id'] = $chat['user_id'];
        $toChat['product'] = $chat['product'];
        $kf = ChatModel::create($toChat);
        $chat['to_chat_id'] = $kf['id'];
        $chat->save();
        return $chat;
    }

    /**
     * 获取排队信息，并执行前进
     * @param $chat
     * @return array
     */
    protected function waitStep($chat): array
    {
        // 查询剩余人数
        $wait = ChatModel::where('user_id', $chat['to_user_id'])
            ->where('to_user_id', '<>', $chat['user_id'])
            ->where('service_status', 0)
            ->where('status', 1)
//            ->where('queue', '>', 0)
//            ->where('queue', '<', $chat['queue'])
            ->count();
        if ($wait == 0) {
            // 正在咨询数量
            $work = ChatModel::where('user_id', $chat['to_user_id'])
                ->where('service_status', 1)
                ->where('status', 1)->count();
            if ($work >= $chat['app']['service_number']) {
                //继续排队
                $tips = '通知 ：现在还有0人，即将接入客服....';
                //记录缓存
                self::setWait($chat['user_id']);
            } else {
                // 接入客服
                $wait = -1;
                $chat['service_status'] = 1;
                $chat['queue'] = 0;
                $chat['service_count'] = $chat['service_count'] + 1;
                $chat->save();

                $kf = ChatModel::where('user_id', $chat['to_user_id'])
                    ->where('service_status', 1)
                    ->where('to_chat_id', $chat['id'])->find();
                if (!$kf) {
                    throw new Exception('数据异常');
                } else {
                    $kf['status'] = 1;
                    $kf['queue'] = 0;
                    $kf['service_status'] = 1;
                    $kf['last_message_time'] = time_format();
                    $kf['service_count'] = $kf['service_count'] + 1;
                    $kf->save();
                }
                self::sendWorkerJob($kf['user_id'], 'customer_access', ['chat_id' => $kf['id']]);
                $tips = '通知 ：已接入客服';
            }
        } else {
            $tips = '通知 ： 现在还有' . $wait . '人在排队，请等待 ....';
            self::setWait($chat['user_id']);
        }
        $systemUser = UserModel::where('id', 10001)->find();
        $data['param'] = $chat['user_id'];
        $data['wait'] = $wait;
        $data['type'] = 'system_tips';
        $data['user_id'] = $systemUser['id'];
        $data['content'] = $tips;
        $data['create_time'] = '刚刚';
        $data['user'] = [
            'id' => $systemUser['id'],
            'avatar_url' => $systemUser['avatar_url'],
            'nickname' => $systemUser['nickname'],
        ];
        return $data;
    }

    /**
     * 获取排队情况
     * @param integer $user_id
     */
    public function getWaitInfo(int $user_id): array
    {
        try {
            $chat = ChatModel::where('user_id', $user_id)->where('status', 1)->where('service_status', 0)->find();
            if (!$chat) {
                throw new Exception('无须排队');
            }
            $data['data'] = $this->waitStep($chat);
            $data['code'] = 0;
        } catch (\Exception $e) {
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
        }
        return $data;
    }

    public function inits($param, $user = null): array
    {
        try {
            $friend = [];
            $groups = ChatGrouping::where('user_id', $user['id'])->field('id,name as groupname')->select();
            if ($groups->isEmpty()) {
                $insert = [
                    'name' => '我的好友',
                    'user_id' => $user['id'],
                ];
                ChatGrouping::create($insert);
                $groups = ChatGrouping::where('user_id', $user['id'])->select();
            }
            foreach ($groups as $index => $group) {
                $list = $user->chats()->order('update_time DESC')->where('chat_grouping_id', $group['id'])->select();
                $tp = $group->toArray();
                $tp['list'] = $this->formatChat($user, $list);
                $friend[] = $tp;
            }
            // 临时会话组

            $list = $user->chats()->order('update_time DESC')->where('chat_grouping_id', null)->select();
            $friend[] = ['groupname' => '临时会话组', 'id' => 1, 'avatar' => 'http://forum.cc/uploads/image/202107/02/60de6e140941c.gif', 'list' => $this->formatChat($user, $list)];
            $mine['avatar'] = $user['avatar_url'];
            $mine['id'] = $user['id'];
            $mine['username'] = $user['nickname'];
            $mine['sign'] = $user['introduction'];
            $mine['type'] = 'friend';
            $data['data']['mine'] = $mine;
//				$data['data']['group'][] =['groupname'=>'群1','id'=>1,'avatar'=>'http://forum.cc/uploads/image/202107/02/60de6e140941c.gif'];
            $data['data']['friend'] = $friend;
            $data['code'] = 0;
        } catch (\Exception $e) {
            $data['message'] = '用户不存在或者您无法与其对话';
            $data['code'] = 1;
        }
        return $data;
    }

    protected function formatChat($user, $list)
    {
        $temp = [];
        foreach ($list as $index => $item) {
//				if ($item['user_id'] == $user['id'])
//				{
            $friend = $item['to_user'];
//				}else{
//					$friend = $item['user'];
//				}
            $temp[] = [
                'id' => $item['id'],
                'name' => $item['remark'],
                'username' => $item['remark'],
//					'username' => $friend['nickname'],
                'avatar' => $friend['avatar_url'],
                'sign' => $friend['introduction'],
                'type' => 'friend',
            ];
        }
        return $temp;
    }

    /**
     * 设置已读
     * @param array $param
     * @param UserModel $user
     */
    public function read($param, $user = null)
    {
        try {
            $chat = $user->chats()->where('status', 1)->where('is_read', 0)->update(['is_read' => 1, 'no_read_count' => 0]);

            // 设置全部已读
            $data['data'] = $chat;
            $data['code'] = 0;
        } catch (\Exception $e) {
            $data['message'] = '用户不存在或者您无法与其对话';
            $data['code'] = 1;
        }
        return $data;
    }


    /**
     * 获取列表
     * @param array $param
     * @param UserModel $user
     * @param null $device
     */
    public function lists($param, $user = null, $device = null)
    {

        $data['data']['lists'] = $user->chats()->with(['to_user' => ['avatar']])->order('last_message_time DESC')
            ->where('service_status', 1)
            ->where('service_status', 1)
            ->paginate(10);
//			$data['data']['info'] = $chat;
        $data['data']['tips'] = '付款前请和卖家确认是否有货，以及瑕疵磨损程度。';
        $data['code'] = 0;
        return $data;
    }

    /**
     * 通知列表提示
     * @param UserModel $user
     * @param $type
     * @param $content
     * @param $to_user_id
     * @return array
     */
    public function otherChat($user, $type = 5, $content = '有新报价', $to_user_id = 10011)
    {
        try {
            // 查询是否已经关联
            $chat = $user->chats()->where('type', $type)
                ->where('to_user_id', $to_user_id)
                ->find();
            if (!$chat) {
                // 创建新聊天
                $chat = [];
                $chat['to_user_id'] = $to_user_id;
                $chat['type'] = $type;
                $chat['new_content'] = $content;
                $chat['content'] = $content;
                $chat['no_read_count'] = 1;
                $chat = $user->chats()->save($chat);
                if (!$chat) {
                    throw new Exception('聊天系统故障');
                }
            } else {
                $chat['new_content'] = $content;
                $chat['content'] = $content;
                $chat['last_message_time'] = time_format();
                $chat['no_read_count'] = $chat['no_read_count'] + 1;
                $chat->save();
            }
            $data['code'] = 0;
            $data['message'] = '发送成功';
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
//				$data['message'] = $e->getMessage();
        }
        return $data;
    }

    /**
     * 聊天详情
     * @param array $param
     * @param UserModel|null $user
     * @param null $device
     */
    public function detail(array $param, UserModel $user = null, $device = null)
    {
        try {
            if (!$user) {
                throw new Exception('用户未登录');
            }
            if (!empty($param['id']) && $param['id'] > 0) {
                // 查询聊天框
                $chat = $user->chats()->with(['to_user' => ['avatar']])->where('id', $param['id'])->find();
                if (!$chat) {
                    throw new Exception('聊天窗口已关闭');
                }
            } else {
                // 查询是否已经关联
                $chat = $user->chats()->with(['to_user' => ['avatar']])
//                    ->where('type', $param['type'])
                    ->where('to_user_id', $param['to_user_id'])
                    ->where('relation_id', isset($param['relation_id']) ? $param['relation_id'] : null)
                    ->find();
                if (!$chat) {
                    $toUser = UserModel::where('id', $param['to_user_id'])->find();
                    if (!$toUser) {
                        throw new Exception('对方不可达');
                    }
                    // 创建新聊天
                    $chat = $this->_initChat($user, $toUser, $param, $device);

//						if ($chat['type'] == 3) {
//							// 发送用户提示
//							$this->otherChat($chat->friend()->find());
//						}
//						// 首次打开有提示
//						$content = [];
//						// 根据不同类型处理
//						$content['type'] = 'trace_tips';
//						$content['content'] = json_encode([
//							'title' => '温馨提示：平台支持7天有理由退货',
//							'tips1' => '通过闲鱼/微信等平台外方式进行交易，',
//							'tips2' => '若遭遇售假、商品与描述不符，平台无法保障您的合法权益。',
//							'tips3' => '为了您的交易安全，请勿脱离平台。',
//						]);
//						$this->_sendChatContent($chat, $content, 'system', $chat['type'] == 3 ? 1 : 0);
                }
            }
            // 全部已读
            $chat['no_read_count'] = 0;
            $chat['read_time'] = time_format();
            $chat->save();
            // 聊天内容
            if (empty($param['content_old_id'])) {
                $data['data']['chat_lists'] = $chat->contents()->order('id DESC')->where('status', 1)->paginate(50);
            } else {
                $data['data']['chat_lists'] = $chat->contents()->order('id DESC')->where('status', 1)->where('id', '<', $param['content_old_id'])->paginate(50);
            }
            $data['data']['info'] = $chat;
            // 在线提示
            //			$data['data']['other_chat_lists'][] = [
            //				'type' => 'system_info',
            //				'content' => '提示：店主在线，您可以直接联系!',
            //			];
            $data['code'] = 0;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'line' . $e->getLine();
        }
        return $data;
    }

    /**
     * 发送聊天消息
     * @param ChatModel $myChat
     * @param array $send
     * @param UserModel|integer $sendUser
     * @param string|null $from
     * @return ChatContentModel
     * @throws Exception
     */
    private function _sendChatContent(ChatModel &$myChat, array $send, $sendUser, string $from = '', $is_robot = false): array
    {
        if (is_numeric($sendUser)) {
            $sendUser = UserModel::where('id', $sendUser)->field('id,type,nickname,avatar_id,avatar_url')->find();
        }
//        if (!$is_robot && $myChat['service_status'] != 1) {
//            throw new Exception('当前的聊天窗口已关闭，无法发送消息');
//        }
        // 更新状态
        $myChat['message_count'] = $myChat['message_count'] + 1;
        $myChat['last_message_time'] = time_format();
        if ($myChat['user_id'] == $sendUser['id']) {
            $myChat['read_time'] = time_format();
            $myChat['is_open'] = 1;
        }
        $content = [];
        // 非文本格式化提示
        if ($send['type'] == 'trace_tips') {
            $content['pre_content'] = '[交易提示]';
        } elseif ($send['type'] == 'image') {
            $content['pre_content'] = '[图片]';
        } elseif ($send['type'] == 'attachment') {
            $content['pre_content'] = '[文件]';
        } else {
            $content['pre_content'] = strip_tags($send['content']);
        }
        //聊天对象
        $toChat = ChatModel::where('id', $myChat['to_chat_id'])->find();
        if (!$toChat) {
            // 新增
            throw new Exception('数据异常');
        } else {
            $toChat['receive_message_time'] = time_format();
            $toChat['last_message_time'] = time_format();
            $toChat['is_read'] = 0;
            $toChat['is_open'] = 1;
            $toChat['new_content'] = $content['pre_content'];
            $toChat['no_read_count'] = $toChat['no_read_count'] + 1;
            $toChat['message_count'] = $toChat['message_count'] + 1;
            $toChat->save();
        }
        $myChat['new_content'] = $content['pre_content'];
        if (!$myChat->save()) {
            throw new Exception('保存失败');
        }
        // 3.新增内容
        // 根据不同类型处理
        $other = [];
        $content['type'] = $send['type'];
        if ($send['type'] == 'image') {
            $file = ImageModel::where('id', $send['relation_id'])->find();
            if (!$file) {
                throw new Exception('服务器内部错误');
            }
        } elseif ($send['type'] == 'attachment') {
            $file = Attachment::where('id', $send['relation_id'])->find();
            if (!$file) {
                throw new Exception('服务器内部错误');
            }
        } else {
            //text
            $content['content'] = $send['content'];
        }
        if (isset($file)) {
            $content['relation_id'] = $file['id'];
            $content['content'] = $file['id'];
            $other['id'] = $file['id'];
            $other['name'] = $file['name'];
            $other['url'] = $file['url'];
        }
        $content['other'] = $other;
        $content['user_id'] = $sendUser['id'];
        $content['to_user_id'] = $myChat['to_user_id'];
        $content['from_chat_id'] = $myChat['id'];
        $content['service_count'] = $toChat['service_count'];
        $content['to_chat_id'] = $toChat['id'];
        $content['ip'] = $send['ip'] ?? '';
        $content['robot_id'] = isset($send['robot_id']) ? $send['robot_id'] : '';
        $content['guid'] = $send['guid'] ?? build_encrypt_key();
        $content = ChatContentModel::create($content);
        $re = ChatContentModel::with(['user', 'to_user'])->where('id', $content['id'])->find()->toArray();
        $re['chat'] = $myChat;
        return $re;
    }

    /**
     * AI消息发送
     * @param $content
     */
    public function aiSend($content)
    {
        try {
            $myChat = ChatModel::where('status', 1)->where('to_chat_id', $content['to_chat_id'])->find();
            if (empty($myChat)) {
                throw new Exception('不合法对2话');
            }
            Db::startTrans();
            $data['data'] = $this->_sendChatContent($myChat, $content, $content['user']['id']);
            Db::commit();
            $data['code'] = 0;
            $data['message'] = '发送成功';
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
//				$data['message'] = $e->getMessage();
        }
        return $data;
    }

    /**
     * 发送消息
     * @param array $param
     * @param UserModel $user
     */
    public function send(array $param, UserModel $user, $device = null, $from = 0)
    {
        try {
            if (!$user) {
                throw new Exception('请登录后发送');
            }
            // 1.查询对话框
            if (empty($param['my_chat_id'])) {
                throw new Exception('不合法对话1');
            }
            $myChat = $user->chats()->where('status', 1)->where('id', $param['my_chat_id'])->find();
            if (empty($myChat)) {
                throw new Exception('不合法对2话');
            }
            Db::startTrans();
            $data['data'] = $this->_sendChatContent($myChat, $param, $user, $from);
            Db::commit();
            $data['code'] = 0;
            $data['message'] = '发送成功';
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
//				$data['message'] = $e->getMessage();
        }
        return $data;
    }


    /**
     * 认领咨询
     * @param array $param
     * @param UserModel $user
     */
    public function receive(array $param, UserModel $user, $device = null, $from = 0)
    {
        try {
            if (!$user) {
                throw new Exception('请登录后发送');
            }
            // 1.查询对话框
            if (empty($param['to_user_id'])) {
                throw new Exception('不合法对话1');
            }
            $myChat = $user->chats()->where('status', 1)->where('to_user_id', $param['to_user_id'])->find();
            if (empty($myChat)) {
                throw new Exception('不合法对2话');
            }
            Db::startTrans();


            $myChat['queue'] = 0;
            $myChat['service_count'] = $myChat['service_count'] + 1;
            $myChat->save();

            $toChat = ChatModel::where('user_id', $myChat['to_user_id'])->where('to_user_id', $myChat['user_id'])->find();
            if (!$toChat) {
                throw new Exception('数据异常');
            }
            $toChat['queue'] = 0;
            $toChat['service_count'] = $toChat['service_count'] + 1;
            $toChat->save();
            $content = '客服' . $user['nickname'] . '即将为您服务';
            // ai机器人
            $ai = UserModel::where('id', config('im.chat_ai'))->field('id,nickname,avatar_id,avatar_url')->find();
            $data['data'] = $this->_sendChatContent($myChat, ['type' => 'text', 'content' => $content], $ai);
            self::sendWorkerJob($myChat['to_user_id'], 'receive', ['content_id' => $data['data']['id']]);
            Db::commit();
            $data['code'] = 0;
            $data['message'] = '发送成功';
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
//				$data['message'] = $e->getMessage();
        }
        return $data;
    }

    /**
     * 转接人工客服
     * @param UserModel $user
     * @param array $param
     * @param $device
     * @return array
     */
    public function switchCustomer(array $param, $device = null)
    {
        try {
            $chat = ChatModel::where('id', $param['chat_id'])->find();
            if (!$chat) {
                throw new Exception('聊天信息不存在');
            }
            $service = UserModel::where('id', $chat->user['store_id'])
                ->where('is_service', 1)
//                ->where('is_online',1)
                ->where('type', 1)->orderRand()->find();
            if (!$service) {
                throw new  Exception('没有在线客服，请稍后再试！');
            }

            $param['customer_id'] = $chat['to_user_id'];
            $param['id'] = $service['id'];
            $data = $this->switch($param, $chat->user);
        } catch (\Exception $e) {
            $data['code'] = 2;
//            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
            $data['message'] = $e->getMessage();
        }
        return $data;
    }

    /**
     * 转接客服
     * @param array $param
     * @param UserModel $user
     */
    public function switch(array $param, UserModel $user, $device = null, $from = 0)
    {
        try {
            if (!$user) {
                throw new Exception('请登录后发送');
            }
            // 1.查询对话框
            if (empty($param['id']) || empty($param['customer_id'])) {
                throw new Exception('参数错误');
            }
            //客服信息
            $myChat = $user->chats()->where('status', 1)->where('to_user_id', $param['customer_id'])->find();
            if (!$myChat) {
                throw new Exception('不合法对话');
            }
            //TODO::客服合法判定
            $toKf = UserModel::where('id', $param['id'])->where('store_id', $myChat['store_id'])->field('id,nickname,avatar_id,avatar_url')->find();
            if (!$toKf) {
                throw new Exception('客服不存在');
            }
            $toChat = ChatModel::where('user_id', $myChat['to_user_id'])->where('to_user_id', $user['id'])->find();
            if (!$toChat) {
                throw new Exception('数据异常');
            }
            Db::startTrans();

            // 正在咨询数量
            $work = ChatModel::where('user_id', $toKf['id'])->where('service_status', 1)->where('status', 1)->count();
            if ($work >= config('im.service_number')) {
                // 需要排队
                $myChat['queue'] = $toKf->chats()->where('service_status', 0)
                        ->where('status', 1)
                        ->where('queue', '>', 0)->max('queue') + 1;
                $myChat['service_status'] = 0;
                $data['message'] = '当前咨询较多，已经为您排队，请耐心等待。';
            } else {
                $myChat['queue'] = 0;
                $myChat['service_status'] = $myChat['service_status'] + 1;
                $data['message'] = '转接成功';
            }
            $myChat['remark'] = $myChat['remark'] . '【' . $user['nickname'] . '】转接';
            $myChat['user_id'] = $toKf['id'];
            $myChat->save();
            $toChat['to_user_id'] = $toKf['id'];
            $toChat['service_status'] = $myChat['service_status'];
            $toChat->save();
            $content = '已经为您分配客服【' . $toKf['nickname'] . '】即将转接。';
            $data['data'] = $this->_sendChatContent($myChat, ['type' => 'text', 'content' => $content], $toKf);
            // 发送消息
            self::sendWorkerJob($myChat['to_user_id'], 'switch_service', ['content_id' => $data['data']['id']]);
            Db::commit();
            $data['code'] = 0;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $data['code'] = 2;
            $data['message'] = 'file:' . $e->getFile() . ',message:' . $e->getMessage() . 'li' . $e->getLine();
//				$data['message'] = $e->getMessage();
        }
        return $data;
    }


    /**
     * 设置已读
     * @param array $param
     * @param UserModel $user
     */
    public function readAll($param, $user, $device = null, $from = 0)
    {
        try {
            if (!$user) {
                throw new Exception('请登录后发送');
            }
            // 1.清理指定会话
            if (!empty($param['chat_id'])) {
                $chats = $user->chats()->where('id', $param['chat_id'])->where('status', 1)->select();
            } else {
                // 所有
                $chats = $user->chats()->where('status', 1)->select();
            }
            foreach ($chats as $chat) {
                $chat['is_read'] = 1;
                $chat['no_read_count'] = 0;
                $chat->save();
            }
            $data['code'] = 0;
            $data['message'] = '操作成功';
        } catch (\Exception $e) {
            $data['code'] = 2;
            $data['message'] = $e->getMessage();
        }
        return $data;
    }

    /**
     * 会话超时提示
     * @param array $param
     * @return array|void
     */
    public static function timeoutTips()
    {
        try {
            $apps = StoreAppModel::where('status', 1)->select();
            foreach ($apps as $app) {
                $chats = ChatModel::where('status', 1)
                    ->where('type', 2)
                    ->where('service_status', 1)
                    ->where('store_app_id', $app['id'])
                    ->where('queue', 0)
                    ->whereTime('receive_message_time', '<', '- ' . $app['chat_timeout_tips'] . ' minute')
                    ->select();
                foreach ($chats as $chat) {
                    if (!Cache::has('tips_service_timeout_tips_' . $chat['id'])) {
                        self::sendWorkerJob($chat['to_user_id'], 'timeout_tips', ['chat_id' => $chat['id']]);
                        Cache::set('tips_service_timeout_tips_' . $chat['id'], 1, $app['chat_timeout_tips'] * 60);
                    }
                }
            }
            $data['code'] = 0;
            $data['message'] = '操作成功';
        } catch (\Exception $e) {
            $data['code'] = 2;
            $data['message'] = $e->getMessage();
        }
        return $data;
    }

    /**
     * 系统关闭超时会话
     * @param array $param
     * @return array|void
     */
    public static function timeoutClose(array $param = [])
    {
        try {
            $apps = StoreAppModel::where('status', 1)->select();
            foreach ($apps as $app) {
                $chats = ChatModel::where('status', 1)
                    ->where('type', 2)
                    ->where('store_app_id', $app['id'])
                    ->where('service_status', 1)
                    ->where('queue', 0)
                    ->whereTime('receive_message_time', '<', '- ' . $app['chat_timeout_close'] . ' minute')
                    ->select();
                foreach ($chats as $chat) {
                    self::_close($chat);
                    self::sendWorkerJob($chat['to_user_id'], 'timeout_close', ['chat_id' => $chat['id'], 'content' => '系统已经关闭了咨询窗口，感谢您的支持！']);
                }
            }
            $data['code'] = 0;
            $data['message'] = '操作成功';
        } catch (\Exception $e) {
            $data['code'] = 2;
            $data['message'] = $e->getMessage();
        }
        return $data;
    }

}
